<template>
	<div class="user">
		<basic-container>
			<el-row :span="24">
				<el-col :xs="24" :sm="24" :md="5" class="user__tree">
					<avue-tree
						:option="treeOption"
						:data="treeData"
						@node-click="nodeClick"
					>
						<span class="el-tree-node__label" slot-scope="{ node, data }">
							<el-tooltip
								class="item"
								effect="dark"
								content="无数据权限"
								placement="right-start"
								v-if="data.isLock"
							>
								<span>{{ node.label }} <i class="el-icon-lock"></i></span>
							</el-tooltip>
							<span v-if="!data.isLock">{{ node.label }}</span>
						</span>
					</avue-tree>
				</el-col>
				<el-col :xs="24" :sm="24" :md="19" class="user__main">
					<avue-crud
						ref="crud"
						:option="option"
						v-model="form"
						:page="page"
						:table-loading="listLoading"
						:before-open="handleOpenBefore"
						:data="list"
						@on-load="getList"
						@search-change="searchChange"
						@refresh-change="refreshChange"
						@size-change="sizeChange"
						@current-change="currentChange"
						@row-update="update"
						@row-save="create"
					>
						<template slot="menuLeft">
							<el-button
								v-if="sys_user_add"
								class="filter-item"
								type="primary"
								size="small"
								icon="el-icon-edit"
								@click="$refs.crud.rowAdd()"
								>添加
							</el-button>
						</template>
						<template slot="username" slot-scope="scope">
							<span>{{ scope.row.username }}</span>
						</template>
						<template slot="role" slot-scope="scope">
							<span v-for="(role, index) in scope.row.roleList" :key="index">
								<el-tag>{{ role.roleName }} </el-tag>&nbsp;&nbsp;
							</span>
						</template>
						<template slot="deptId" slot-scope="scope">
							<el-tag>{{ scope.row.deptName }}</el-tag
							>&nbsp;&nbsp;
						</template>
						<template slot="post" slot-scope="scope">
							<span v-for="(post, index) in scope.row.postList" :key="index">
								<el-tag>{{ post.name }} </el-tag>&nbsp;&nbsp;
							</span>
						</template>
						<template slot="lockFlag" slot-scope="scope">
							{{ scope.label }}
						</template>
						<template slot="menu" slot-scope="scope">
							<el-button
								v-if="sys_user_edit"
								type="text"
								size="small"
								icon="el-icon-edit"
								@click="handleUpdate(scope.row, scope.index)"
								>编辑
							</el-button>
							<el-button
								v-if="sys_user_del"
								type="text"
								size="small"
								icon="el-icon-delete"
								@click="deletes(scope.row, scope.index)"
								>删除
							</el-button>
						</template>
						<template slot="deptIdForm" slot-scope="scope">
							<avue-input-tree
								v-model="form.deptId"
								:node-click="getNodeData"
								:dic="treeDeptData"
								:props="defaultProps"
								placeholder="请选择所属部门"
							/>
						</template>
						<template slot="roleForm" slot-scope="scope">
							<avue-select
								v-model="role"
								:dic="rolesOptions"
								:props="roleProps"
								multiple
								placeholder="请选择角色"
							/>
						</template>
						<template slot="postForm" slot-scope="scope">
							<avue-select
								v-model="post"
								:dic="postsOptions"
								:props="postProps"
								multiple
								placeholder="请选择岗位"
							/>
						</template>
						<template slot="totpForm" slot-scope="scope">
							<el-input v-model="form.totp" type="text" clearable>
								<i
									slot="suffix"
									class="el-icon-view el-input__icon"
									style="color: black"
									@click="showTotp"
								/>
							</el-input>
						</template>
					</avue-crud>
				</el-col>
			</el-row>
		</basic-container>
	</div>
</template>

<script>
	import {
		addObj,
		delObj,
		fetchList,
		putObj,
		getTotpByUserId,
	} from "@/api/admin/user";
	import { deptRoleList, deptScopeRoleList } from "@/api/admin/role";
	import { deptPostList } from "@/api/admin/post";
	import { fetchTree } from "@/api/admin/dept";
	import { tableOption } from "@/const/crud/admin/user";
	import { mapGetters } from "vuex";

	export default {
		name: "SysUser",
		data() {
			return {
				searchForm: {},
				treeOption: {
					nodeKey: "id",
					addBtn: false,
					menu: false,
					props: {
						label: "name",
						value: "id",
					},
				},
				treeData: [],
				option: tableOption,
				treeDeptData: [],
				checkedKeys: [],
				roleProps: {
					label: "roleName",
					value: "roleId",
				},
				sys_user_add: false,
				sys_user_edit: false,
				sys_user_del: false,
				defaultProps: {
					label: "name",
					value: "id",
				},
				page: {
					total: 0, // 总页数
					currentPage: 1, // 当前页数
					pageSize: 20, // 每页显示多少条,
					isAsc: false, // 是否倒序
				},
				list: [],
				listLoading: true,
				role: [],
				form: {},
				rolesOptions: [],
				post: [],
				postsOptions: [],
				postProps: {
					label: "name",
					value: "postId",
				},
			};
		},
		computed: {
			...mapGetters(["permissions"]),
		},
		watch: {
			role() {
				this.form.role = this.role;
			},
			post() {
				this.form.post = this.post;
			},
		},
		created() {
			this.sys_user_add = this.permissions["sys_user_add"];
			this.sys_user_edit = this.permissions["sys_user_edit"];
			this.sys_user_del = this.permissions["sys_user_del"];
			this.init();
		},
		methods: {
			showTotp() {
				getTotpByUserId(this.form.userId)
					.then((resp) => {
						if (resp.data.code === 0) {
							this.form.totp = resp.data.data.totp;
						} else {
							this.$message.error(resp.data.msg);
						}
					})
					.catch((error) => {
						console.log(error);
						this.$message.error("请求获取TOTP失败");
					});
			},
			init() {
				fetchTree().then((response) => {
					this.treeData = response.data.data;
				});
			},
			nodeClick(data) {
				this.page.page = 1;
				this.getList(this.page, { deptId: data.id });
			},
			getList(page, params) {
				this.listLoading = true;
				fetchList(
					Object.assign(
						{
							current: page.currentPage,
							size: page.pageSize,
						},
						params,
						this.searchForm
					)
				).then((resp) => {
					if (resp.data.code === 0) {
						this.list = resp.data.data.records;
						this.page.total = resp.data.data.total;
					} else {
						this.$message.error(resp.data.msg);
					}
					this.listLoading = false;
				});
			},
			getNodeData() {
				deptScopeRoleList().then((response) => {
					this.rolesOptions = response.data.data;
				});
				deptPostList().then((resp) => {
					this.postsOptions = resp.data.data;
				});
			},
			searchChange(param, done) {
				this.searchForm = param;
				this.page.currentPage = 1;
				this.getList(this.page, param);
				done();
			},
			sizeChange(pageSize) {
				this.page.pageSize = pageSize;
			},
			currentChange(current) {
				this.page.currentPage = current;
			},
			refreshChange() {
				this.getList(this.page);
			},
			markTreeNode(tree) {
				tree.forEach((e) => {
					if (e.isLock) {
						e.disabled = true;
					}
					this.markTreeNode(e.children);
				});
			},
			handleOpenBefore(show, type) {
				window.boxType = type;
				// 查询部门树
				fetchTree().then((response) => {
					const tree = response.data.data;
					this.markTreeNode(tree);
					this.treeDeptData = tree;
				});
				// 查询角色列表
				deptScopeRoleList().then((response) => {
					this.rolesOptions = response.data.data;
				});
				// 查询岗位列表
				deptPostList().then((resp) => {
					this.postsOptions = resp.data.data;
				});

				if (["edit", "views"].includes(type)) {
					this.role = [];
					for (let i = 0; i < this.form.roleList.length; i++) {
						this.role[i] = this.form.roleList[i].roleId;
					}
					this.post = [];
					for (let i = 0; i < this.form.postList.length; i++) {
						this.post[i] = this.form.postList[i].postId;
					}
				} else if (type === "add") {
					this.role = [];
					this.post = [];
				}
				show();
			},
			handleUpdate(row, index) {
				this.$refs.crud.rowEdit(row, index);
				this.form.password = undefined;
			},
			create(row, done, loading) {
				console.log("create");
				if (this.form.phone.indexOf("*") > 0) {
					this.form.phone = undefined;
				}
				addObj(this.form)
					.then((resp) => {
						if (resp.data.code === 0) {
							this.getList(this.page);
							done();
							const username = this.form.username;
							const password = this.form.password;
							const info = `
              <div>用户名：${this.form.username}</div>
              <div>密码：${this.form.password}</div>
              <div>MFA：<img src="${resp.data.data.img}"></div>
              `;
							this.$confirm(info, "添加用户成功", {
								dangerouslyUseHTMLString: true,
								distinguishCancelAndClose: true,
								confirmButtonText: "确定",
								cancelButtonText: "下载",
							}).catch((action) => {
								if (action === "cancel") {
									let str = `用户名,密码,MFA,\n${username},${password},${resp.data.data.totp},\n`;
									//encodeURIComponent解决中文乱码
									let uri =
										"data:text/csv;charset=utf-8,\ufeff" +
										encodeURIComponent(str);
									//通过创建a标签实现
									var link = document.createElement("a");
									link.href = uri;
									//对下载的文件命名
									link.download = "用户信息.csv";
									document.body.appendChild(link);
									link.click();
									document.body.removeChild(link);
								}
							});
						} else {
							this.$message.error(resp.data.msg);
						}
					})
					.catch(() => {
						loading();
					});
			},
			update(row, index, done, loading) {
				if (this.form.phone && this.form.phone.indexOf("*") > 0) {
					this.form.phone = undefined;
				}
				if (this.form.totp && this.form.totp.indexOf("*") > 0) {
					this.form.totp = undefined;
				}
				putObj(this.form)
					.then(() => {
						this.getList(this.page);
						done();
						this.$notify.success("修改成功");
					})
					.catch(() => {
						loading();
					});
			},
			deletes(row, index) {
				this.$confirm(
					"此操作将永久删除该用户(用户名:" + row.username + "), 是否继续?",
					"警告",
					{
						confirmButtonText: "确定",
						cancelButtonText: "取消",
						type: "warning",
					}
				).then(() => {
					delObj(row.userId)
						.then(() => {
							this.list.splice(index, 1);
							this.$notify.success("删除成功");
						})
						.catch(() => {
							this.$notify.error("删除失败");
						});
				});
			},
		},
	};
</script>
<style lang="scss">
	.user {
		height: 100%;

		&__tree {
			padding-top: 3px;
			padding-right: 20px;
		}

		&__main {
			.el-card__body {
				padding-top: 0;
			}
		}
	}
</style>
